//给你一个下标从 0 开始的字符串 s ，该字符串由用户输入。按键变更的定义是：使用与上次使用的按键不同的键。例如 s = "ab" 表示按键变更一次，而 
//s = "bBBb" 不存在按键变更。 
//
// 返回用户输入过程中按键变更的次数。 
//
// 注意：shift 或 caps lock 等修饰键不计入按键变更，也就是说，如果用户先输入字母 'a' 然后输入字母 'A' ，不算作按键变更。 
//
// 
//
// 示例 1： 
//
// 
//输入：s = "aAbBcC"
//输出：2
//解释： 
//从 s[0] = 'a' 到 s[1] = 'A'，不存在按键变更，因为不计入 caps lock 或 shift 。
//从 s[1] = 'A' 到 s[2] = 'b'，按键变更。
//从 s[2] = 'b' 到 s[3] = 'B'，不存在按键变更，因为不计入 caps lock 或 shift 。
//从 s[3] = 'B' 到 s[4] = 'c'，按键变更。
//从 s[4] = 'c' 到 s[5] = 'C'，不存在按键变更，因为不计入 caps lock 或 shift 。
// 
//
// 示例 2： 
//
// 
//输入：s = "AaAaAaaA"
//输出：0
//解释： 不存在按键变更，因为这个过程中只按下字母 'a' 和 'A' ，不需要进行按键变更。
// 
// 
//
// 
//
// 提示： 
//
// 
// 1 <= s.length <= 100 
// s 仅由英文大写字母和小写字母组成。 
// 
//
// Related Topics 字符串 👍 20 👎 0


package LeetCode.editor.cn;

/**
 * @author ldltd
 * @date 2025-01-07 23:27:30
 * @description 3019.按键变更的次数
 */
public class NumberOfChangingKeys{
	 public static void main(String[] args) {
	 	 //测试代码
	 	 NumberOfChangingKeys fun=new NumberOfChangingKeys();
	 	 Solution solution = fun.new Solution();

	 }
	 
//力扣代码
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
    public int countKeyChanges1(String s) {
		if (s == null || s.isEmpty()) {
			return 0;
		}
		return (int) s.chars()
				.mapToObj(c -> (char) c)
				.reduce(new Object[] {s.charAt(0), 0}, (acc, c) -> {
					if (Character.toUpperCase((char) acc[0]) != Character.toUpperCase(c)) {
						acc[1] = (int) acc[1] + 1;
					}
					acc[0] = c;
					return acc;
				}, (acc1, acc2) -> acc1)[1];
	}
	/*对于同一字母的大写和小写，ASCII 值的二进制的低 5 位是相同的，所以只需统计

	s[i−1]&31不等于s[i]&31的个数。

	其中 &31 表示取二进制的低 5 位。*/
	public int countKeyChanges(String s) {
		if (s == null || s.isEmpty()) {
			return 0;
		}

		return (int) s.chars()
				.map(c -> (char)c & 31) // 提取低 5 位
				.boxed()
				.reduce(new int[] {-1, 0}, (acc, curr) -> {
					// acc[0]: 保存前一个字符的低 5 位
					// acc[1]: 计数器
					if (acc[0] != -1 && acc[0] != curr) {
						acc[1]++; // 如果当前字符不同于前一个字符，计数器加 1
					}
					acc[0] = curr; // 更新前一个字符
					return acc;
				}, (acc1, acc2) -> acc1)[1]; // 返回计数器值
	}

}
//leetcode submit region end(Prohibit modification and deletion)

}
